//给定一个字符串 s，找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 
//
// 示例 1： 
//
// 输入: "babad"
//输出: "bab"
//注意: "aba" 也是一个有效答案。
// 
//
// 示例 2： 
//
// 输入: "cbbd"
//输出: "bb"
// 
// Related Topics 字符串 动态规划 
// 👍 2533 👎 0

package leetcode.editor.cn;

//Java：最长回文子串
public class P5LongestPalindromicSubstring {

    //leetcode submit region begin(Prohibit modification and deletion)
    /**
     * 思路：动态规划, 三个步骤，
     * 1. 先定义一个数组赋予它意义： arr[i][j] 代表 从s.substring(i,j+1) 是否是回文
     * 2. 找出关系式：  arr[i][j] 是回文，代表  arr[i][j] = arr[i+1][j-1] 为true && s.charAt(i)==s.charAt(j)
     * 3. 找出初始值： arr[i][i] = true;  arr[i][i+1] = s.charAt(i)==s.charAt(i+1)
     *
     * 然后就是要保证 [i+1][j-1] 已经判断过了，就是向外扩张，所以 i 降，j 升循环
     *
     * 执行用时： 127 ms , 在所有 Java 提交中击败了 32.14% 的用户 内存消耗： 42.9 MB , 在所有 Java 提交中击败了 10.83% 的用户
     */
    class Solution {
        public String longestPalindrome(String s) {
            int sLength = s.length();
            if(sLength == 0){
                return "";
            }
            boolean[][] arr = new boolean[sLength][sLength];
            int min = 0;
            int max = 0;

            // 构造初始值
            for (int i = 0; i < sLength; i++) {
                arr[i][i] = true;
                if (i < sLength - 1) {
                    boolean flag = s.charAt(i) == s.charAt(i + 1);
                    if (flag) {
                        min = i;
                        max = i + 1;
                    }
                    arr[i][i + 1] = flag;
                }
            }

            for (int i = sLength - 2; i >= 0; i--) {
                for (int j = i + 2; j < sLength; j++) {
                    if (s.charAt(i) == s.charAt(j) && arr[i + 1][j - 1]) {
                        // i - j 是回文
                        if ((j - i) > (max - min)) {
                            max = j;
                            min = i;
                        }
                        arr[i][j] = true;
                    } else {
                        arr[i][j] = false;
                    }
                }
            }
            return s.substring(min, max + 1);
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)

    public static void main(String[] args) {
        String s = "";
        Solution solution = new P5LongestPalindromicSubstring().new Solution();
        System.out.println(solution.longestPalindrome(s));
        // TO TEST
    }

}